package spoon.service;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import spoon.core.domain.Game;

@Service
@Qualifier("marathonFootballService")
public class MarathonFootballService extends MarathonAbstractService {

	@Resource(name = "marathon.football.league")
	protected void getLeagueMap(Map<String, String> map) {
		this.leagueMap = map;
	}

	@Resource(name = "marathon.football.team")
	protected void getTeamMap(Map<String, String> map) {
		this.teamMap = map;
	}

	@Value("#{marathon['football.itemCode']}")
	protected void getItemCode(String itemCode) {
		this.ITEM_CODE = itemCode;
	}

	@Value("#{marathon['football.itemName']}")
	protected void getItemName(String itemName) {
		this.ITEM_NAME = itemName;
	}

	@Value("#{marathon['football.url']}")
	protected void getGateUrl(String url) {
		this.GATE_URL = url;
	}

	@Override
	public void getGame(Element element) {
		long startTime = System.currentTimeMillis();

		int gameCnt = 0;
		int bettingCnt = 0;

		Game league = new Game();

		// H2 <span class="nowrap">Argentina.</span> <span
		// class="nowrap">Primera Division</span>
		setLeagueInfo(league, element.select("h2 span"));
		league.setGameId(element.attr("id"));
		league.setSite(SITE);
		league.setUrl(URL);
		league.setItemName(ITEM_NAME);
		league.setItemCode(ITEM_CODE);

		// 게임
		Elements tbodis = element.select("table.foot-market > tbody");
		// 첫번째는 테이블제목 빼 준다.
		tbodis.remove(0);

		for (Element tbody : tbodis) {
			Game game = new Game();
			boolean isToday = true;
			Elements teams = tbody.select(".today-member-name");
			if (teams.size() == 0) {
				teams = tbody.select(".member-name");
				isToday = false;
			}
			game.setHomeTeamName(teams.get(0).text());
			game.setAwayTeamName(teams.get(1).text());

			game.setHomeTeamCode(getTeamCode(game.getHomeTeamName()));
			game.setAwayTeamCode(getTeamCode(game.getAwayTeamName()));

			if (isToday) {
				game.setGameDate(convertTodayDate(tbody.select(".date").text()));
			} else {
				game.setGameDate(convertDate(tbody.select(".date").text()));
			}

			// 링크 http://www.marathonbet.com/en/markets.htm, POST
			// treeId={treeId}
			game.setLink(tbody.attr("data-event-treeid"));

			this.getGameList(game, tbody);
			league.addGameList(game);

			gameCnt++;
		}

		// 데이터 입력
		if (league.getGameList().size() > 0) {
			bettingCnt = addBetting(league);
		}

		log.info("사이트: {}, 종목: {}, 국가: {}, 리그: {}, 경기수: {}, 베팅수: {}, 소요시간: {}초", SITE, ITEM_CODE, league.getNation(), league.getLeagueName(), gameCnt,
				bettingCnt, (System.currentTimeMillis() - startTime) / 1000.0f);

	}

	private void getGameList(Game game, Element element) {
		// 팀명, 1, X, 2, 1X, 12, X2, Handicap Home, Handicap Away, Under, Over -
		// 10개 수작업
		Elements tds = element.select("td.js-price");

		for (Element td : tds) {
			if (!td.text().contains("/")) {
				continue;
			}
			
			Game betting = new Game();
			betting.setBetTarget("Goals");
			betting.setBetTime("FT");
			String type = td.attr("data-mutable-id");
			
			switch (type) {
			case "S1": // 1X2 홈팀
				betting.setBetType("1X2");
				betting.setBetName("1X2");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName(game.getHomeTeamCode());
				betting.setBetRateCode("1");
				game.addGameList(betting);
				break;
			case "S2": // 1X2 Draw
				betting.setBetType("1X2");
				betting.setBetName("1X2");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName("Draw");
				betting.setBetRateCode("X");
				game.addGameList(betting);
				break;
			case "S3": // 1X2 원정팀
				betting.setBetType("1X2");
				betting.setBetName("1X2");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName(game.getAwayTeamCode());
				betting.setBetRateCode("1");
				game.addGameList(betting);
				break;
			case "S4": // Double Chance 1X
				betting.setBetType("DC");
				betting.setBetName("Double Chance");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName("1X");
				betting.setBetRateCode("1X");
				game.addGameList(betting);
				break;
			case "S5": // Double Chance 12
				betting.setBetType("DC");
				betting.setBetName("Double Chance");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName("12");
				betting.setBetRateCode("12");
				game.addGameList(betting);
				break;
			case "S6": // Double Chance X2
				betting.setBetType("DC");
				betting.setBetName("Double Chance");
				betting.setHandicap(0D);
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.text()));
				betting.setBetRateName("X2");
				betting.setBetRateCode("X2");
				game.addGameList(betting);
				break;
			case "S7": // Handicap Home
				betting.setBetType("H");
				betting.setBetName("Handicap");
				betting.setHandicap(convertHandicap(td.ownText()));
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.select("span").text()));
				betting.setBetRateName("1");
				betting.setBetRateCode("1");
				game.addGameList(betting);
				break;
			case "S8": // Handicap Away
				betting.setBetType("H");
				betting.setBetName("Handicap");
				betting.setHandicap(convertHandicap(td.ownText()));
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.select("span").text()));
				betting.setBetRateName("2");
				betting.setBetRateCode("2");
				game.addGameList(betting);
				break;
			case "S9": // Over Under - Under
				betting.setBetType("OU");
				betting.setBetName("Over Under");
				betting.setHandicap(convertHandicap(td.ownText()));
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.select("span").text()));
				betting.setBetRateName("Under");
				betting.setBetRateCode("Under");
				game.addGameList(betting);
				break;
			case "S10": // Over Under - Over
				betting.setBetType("OU");
				betting.setBetName("Over Under");
				betting.setHandicap(convertHandicap(td.ownText()));
				betting.setHandicapName("");
				betting.setBetRate(convertRate(td.select("span").text()));
				betting.setBetRateName("Over");
				betting.setBetRateCode("Over");
				game.addGameList(betting);
				break;
			}
		}

		if (!"".equals(element.select(".more-view").text())) {
			this.getBettingList(game);
		}
	}

	/**
	 * 링크 http://www.marathonbet.com/en/markets.htm, POST treeId={treeId}
	 * 
	 * @param league
	 */
	private void getBettingList(Game game) {
		String source = httpService.getSource(LINK, "treeId=" + game.getLink());
		if ("".equals(source)) {
			log.error("링크 : {}, 파라메타: {}, 접속할 수 없습니다.", LINK, game.getLink());
			return;
		}

		source = source.replaceAll("\\\\r\\\\n", "").replaceAll("\\\\n", "").replaceAll("\\\\\"", "\"").replaceAll("\\\\/", "/");
		source = source.substring(source.indexOf("<"), source.lastIndexOf(">") + 1);
		
		Elements elements = Jsoup.parse(source).select("div.blocks-area > div");
		
		for (Element div : elements) {
			
			String title = div.select(".market-block-name-menu").get(0).text();
			
			if ("Handicap Markets".equals(title)) { // Handicap Markets
				this.getHandicap(game, div);
			} else if ("Total Markets".equals(title)) { // Total Markets
				this.getTotalGame(game, div);
			} else if ("Half Markets".equals(title)) { // Half Markets
				this.getHalfGame(game, div);
			}

		}

	}
	
	/**
	 * 핸디캡 베팅 설정
	 * 
	 * @param game
	 * @param div
	 */
	private void getHandicap(Game game, Element element) {
		
		Elements divs = element.select("div.market-inline-block-table-wrapper");
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("betTarget", "Goals");
		map.put("betType", "H");
		
		for (Element div : divs) {
			String title = div.select(".market-table-name").get(0).ownText();
			// 홈팀, 원정팀은 class="aleft"다.
			Elements tds = div.select("td");
			
			if ("Handicap".equals(title)) { // 핸디캡
				map.put("betTime", "FT");
				map.put("betName", "Handicap");
				betHandicap(game, map, tds);
			} else if ("Asian Handicap".equals(title)) { // Asian Handicap
				map.put("betTime", "FT");
				map.put("betName", "Asian Handicap");
				betHandicap(game, map, tds);
			} else if ("1st Half Handicap".equals(title)) { // 1st Half Handicap
				map.put("betTime", "1H");
				map.put("betName", "1st Half Handicap");
				betHandicap(game, map, tds);
			} else if ("2nd Half Handicap".equals(title)) { // 2nd Half Handicap
				map.put("betTime", "2H");
				betHandicap(game, map, tds);
			}
		}
	}
	
	/**
	 * Total Markets 설정
	 * 
	 * @param game
	 * @param element
	 */
	private void getTotalGame(Game game, Element element) {
		Elements divs = element.select("div.market-inline-block-table-wrapper");
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("betTarget", "Goals");
		map.put("betType", "OU");
		
		for (Element div : divs) {
			String title = div.select(".market-table-name").get(0).ownText();
			Elements trs = div.select("tr");
			
			if ("Total Goals".equals(title)) { // Total Goals
				map.put("betTime", "FT");
				map.put("betName", "Total Goals");
				betOverUnder(game, map, trs);
			} else if ("Total Goals - 1st Half".equals(title)) { // Total Goals - 1st Half
				map.put("betTime", "1H");
				map.put("betName", "Total Goals - 1st Half");
				betOverUnder(game, map, trs);
			} else if ("Total Goals - 2nd Half".equals(title)) { // Total Goals - 2nd Half
				map.put("betTime", "2H");
				betOverUnder(game, map, trs);
			}
		}
		
	}
	
	/**
	 * Half Markets 설정
	 * 
	 * @param game
	 * @param element
	 */
	private void getHalfGame(Game game, Element element) {
		Elements divs = element.select("div.market-inline-block-table-wrapper");
		
		Map<String, String> map = new HashMap<String, String>();
		map.put("betTarget", "Goals");
		
		for (Element div : divs) {
			String title = div.select(".market-table-name").get(0).ownText();
			Elements trs = div.select("div.highlight-name-price");
			// Result는 정해져 있다. 순서대로 1, 1X, X, 12, 2, X2의 순서
			if ("1st Half Result".equals(title)) { // 1st Half Result
				map.put("betTime", "1H");
				betHalfMatch(game, map, trs);
			} else if ("2nd Half Result ".equals(title)) { // 2nd Half Result
				map.put("betTime", "2H");
				betHalfMatch(game, map, trs);
			}
		}
		
	}

}
